package com.example.chat.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import com.example.chat.handler.ChatWebSocketHandler;
import com.example.chat.interceptor.WebSocketInterceptor;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * WebSocket 配置类

 * 该配置类负责设置和管理应用程序中的 WebSocket 连接。WebSocket 是一种在单个 TCP 连接上
 * 提供全双工通信的协议，特别适用于实时通信应用，如聊天系统。
 * 主要功能：
 * 1. 启用 Spring 的 WebSocket 支持
 * 2. 注册 WebSocket 处理器和拦截器
 * 3. 配置 WebSocket 端点和安全策略
 * 4. 设置会话处理和消息路由
 */
@Configuration
@EnableWebSocket  // 启用 Spring WebSocket 支持
public class WebSocketConfig implements WebSocketConfigurer {

    /**
     * 注入聊天 WebSocket 处理器
     * 该处理器负责处理接收到的 WebSocket 消息，管理会话连接和消息分发
     */
    @Autowired
    private ChatWebSocketHandler webSocketHandler;

    /**
     * 注册 WebSocket 处理器和拦截器
     * 此方法定义了：
     * 1. WebSocket 的访问路径 (/ws/chat)
     * 2. 添加请求拦截器进行身份验证和会话预处理
     * 3. 设置跨域访问策略
     * 
     * @param registry WebSocket 处理器注册表，用于注册处理器和配置其属性
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // 注册WebSocket处理器，配置处理器拦截的路径
        registry.addHandler(webSocketHandler, "/ws/chat")
                .addInterceptors(new WebSocketInterceptor())  // 添加拦截器用于身份验证和会话处理
                .setAllowedOrigins("*"); // 允许所有来源，生产环境应该限制来源
    }

    /**
     * 注册 ServerEndpointExporter Bean
     * ServerEndpointExporter 是一个 Spring 组件，用于扫描并注册使用 @ServerEndpoint 注解的类，
     * 使其能够作为 WebSocket 端点。它将这些端点注册到底层的 WebSocket 容器中。
     * 该 Bean 主要用于支持基于注解的 WebSocket 端点，而非基于接口的 WebSocket 处理器。
     * 在本应用中，我们使用了两种 WebSocket 实现方式，这个 Bean 支持基于注解的方式。
     * @return ServerEndpointExporter 实例
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
} 